home *** CD-ROM | disk | FTP | other *** search
/ Aminet 12 / Aminet 12 (1996)(GTI - Schatztruhe)[!][Jun 1996].iso / Aminet / dev / c / MultiList.lha / MultiList.c next >
Encoding:
C/C++ Source or Header  |  1996-03-21  |  14.0 KB  |  505 lines

  1. /* This is an example of implementing Multi Select Gadtools
  2.  * ListViews with OS3.0+.
  3.  *
  4.  * m goes down list
  5.  * M up
  6.  * Spaces toggles selection
  7.  *
  8.  * Note - The list view can not be drawn as disabled.
  9.  *
  10.  * mark@topic.demon.co.uk
  11.  * mpaddock@cix.compulink.co.uk
  12.  *
  13.  * Use Freely!
  14.  */
  15.  
  16. #include <proto/intuition.h>
  17. #include <proto/gadtools.h>
  18. #include <proto/graphics.h>
  19. #include <proto/exec.h>
  20. #include <string.h>
  21.  
  22. int __osversion=39;
  23. /*
  24.  *  Source machine generated by GadToolsBox V2.0b
  25.  *  which is (c) Copyright 1991-1993 Jaba Development
  26.  *
  27.  *  GUI Designed by : M J P
  28.  */
  29.  
  30. #define GetString( g )      ((( struct StringInfo * )g->SpecialInfo )->Buffer  )
  31. #define GetNumber( g )      ((( struct StringInfo * )g->SpecialInfo )->LongInt )
  32.  
  33. #define GD_MList                               0
  34.  
  35. #define GDX_MList                              0
  36.  
  37. #define MultiList_CNT 1
  38.  
  39. extern struct IntuitionBase *IntuitionBase;
  40. extern struct Library       *GadToolsBase;
  41.  
  42. extern struct Screen        *Scr;
  43. extern UBYTE                 *PubScreenName;
  44. extern APTR                  VisualInfo;
  45. extern struct Window        *MultiListWnd;
  46. extern struct Gadget        *MultiListGList;
  47. extern struct IntuiMessage   MultiListMsg;
  48. extern struct Gadget        *MultiListGadgets[1];
  49. extern UWORD                 MultiListLeft;
  50. extern UWORD                 MultiListTop;
  51. extern UWORD                 MultiListWidth;
  52. extern UWORD                 MultiListHeight;
  53. extern UBYTE                *MultiListWdt;
  54. extern struct TextAttr      *Font, Attr;
  55. extern UWORD                 FontX, FontY;
  56. extern UWORD                 OffX, OffY;
  57. extern struct MinList        MList0List;
  58. extern UWORD                 MultiListGTypes[];
  59. extern struct NewGadget      MultiListNGad[];
  60. extern ULONG                 MultiListGTags[];
  61.  
  62. extern int MListClicked( void );
  63.  
  64. extern int SetupScreen( void );
  65. extern void CloseDownScreen( void );
  66. extern int HandleMultiListIDCMP( void );
  67. extern int MultiListCloseWindow(void);
  68. extern int MultiListVanillaKey(void);
  69. extern int OpenMultiListWindow( void );
  70. extern void CloseMultiListWindow( void );
  71.  
  72. struct ExtNode {
  73.   struct Node Node;
  74.   BOOL Selected;
  75.   BOOL Current;
  76. };
  77.  
  78. /*
  79.  *  Source machine generated by GadToolsBox V2.0b
  80.  *  which is (c) Copyright 1991-1993 Jaba Development
  81.  *
  82.  *  GUI Designed by : M J P
  83.  */
  84.  
  85.  
  86. struct Screen         *Scr = NULL;
  87. UBYTE                 *PubScreenName = NULL;
  88. APTR                   VisualInfo = NULL;
  89. struct Window         *MultiListWnd = NULL;
  90. struct Gadget         *MultiListGList = NULL;
  91. struct IntuiMessage    MultiListMsg;
  92. struct Gadget         *MultiListGadgets[1];
  93. UWORD                  MultiListLeft = 205;
  94. UWORD                  MultiListTop = 155;
  95. UWORD                  MultiListWidth = 172;
  96. UWORD                  MultiListHeight = 75;
  97. UBYTE                 *MultiListWdt = (UBYTE *)"Multi Select";
  98. struct TextAttr       *Font, Attr;
  99. UWORD                  FontX, FontY;
  100. UWORD                  OffX, OffY;
  101.  
  102. extern struct MinList MList0List;
  103.  
  104. struct ExtNode MList0Nodes[] = {
  105.     (struct Node *)&MList0Nodes[1], ( struct Node * )&MList0List.mlh_Head, 0, 0, "Entry0",FALSE,FALSE,
  106.     (struct Node *)&MList0Nodes[2], (struct Node *)&MList0Nodes[0], 0, 0, "Entry1",FALSE,TRUE,
  107.     (struct Node *)&MList0Nodes[3], (struct Node *)&MList0Nodes[1], 0, 0, "Entry2",TRUE,FALSE,
  108.     (struct Node *)&MList0Nodes[4], (struct Node *)&MList0Nodes[2], 0, 0, "Entry3",TRUE,FALSE,
  109.     (struct Node *)&MList0Nodes[5], (struct Node *)&MList0Nodes[3], 0, 0, "Entry4",FALSE,FALSE,
  110.     (struct Node *)&MList0Nodes[6], (struct Node *)&MList0Nodes[4], 0, 0, "Entry5",FALSE,FALSE,
  111.     (struct Node *)&MList0Nodes[7], (struct Node *)&MList0Nodes[5], 0, 0, "Entry6",FALSE,FALSE,
  112.     (struct Node *)&MList0Nodes[8], (struct Node *)&MList0Nodes[6], 0, 0, "Entry7",FALSE,FALSE,
  113.     (struct Node *)&MList0Nodes[9], (struct Node *)&MList0Nodes[7], 0, 0, "Entry8",FALSE,FALSE,
  114.     ( struct Node * )&MList0List.mlh_Tail, (struct Node *)&MList0Nodes[8], 0, 0, "Entry9",FALSE,FALSE};
  115.  
  116. #define ENTRYCOUNT 10
  117. int CurEntry = 1;
  118.  
  119. struct MinList MList0List = {
  120.     ( struct MinNode * )&MList0Nodes[0], ( struct MinNode * )NULL, ( struct MinNode * )&MList0Nodes[9] };
  121.  
  122. UWORD MultiListGTypes[] = {
  123.     LISTVIEW_KIND
  124. };
  125.  
  126. struct NewGadget MultiListNGad[] = {
  127.     3, 15, 167, 60, (UBYTE *)"_Multi Select List", NULL, GD_MList, PLACETEXT_ABOVE, NULL, (APTR)MListClicked
  128. };
  129.  
  130. struct Hook                  HookList = {0};
  131.  
  132. ULONG MultiListGTags[] = {
  133.     (GTLV_Labels), (ULONG)&MList0List, (GT_Underscore), '_', GTLV_CallBack,    (ULONG)&HookList, (TAG_DONE)
  134. };
  135.  
  136. ULONG __saveds __asm HookEntryList(register __a0 struct Hook *Hook,
  137.                      register __a2 struct ExtNode *ExtNode,
  138.                      register __a1 struct LVDrawMsg *msg) {
  139.   char buffer[2];
  140.   ULONG len;
  141.   WORD length;
  142.   struct TextExtent textExtent;
  143.   if (msg->lvdm_MethodID != LV_DRAW) {
  144.     return LVCB_UNKNOWN;
  145.   }
  146.   switch(msg->lvdm_State) {
  147.   case LVR_NORMAL:
  148.   case LVR_NORMALDISABLED:
  149.   case LVR_SELECTED:
  150.   case LVR_SELECTEDDISABLED:
  151.     Move(msg->lvdm_RastPort,msg->lvdm_Bounds.MinX,
  152.          msg->lvdm_Bounds.MinY+msg->lvdm_RastPort->TxBaseline);
  153.     length = TextLength(msg->lvdm_RastPort,"*",1);
  154.      if (ExtNode->Current) {
  155.       buffer[0] = '*';
  156.     }
  157.     else {
  158.       buffer[0] = ' ';
  159.     }
  160.     buffer[1]=0;
  161.     len = TextFit(msg->lvdm_RastPort,ExtNode->Node.ln_Name,
  162.           strlen(ExtNode->Node.ln_Name),&textExtent,NULL,1,
  163.           msg->lvdm_Bounds.MaxX-msg->lvdm_Bounds.MinX+1-length,32767);
  164.     if (!ExtNode->Selected) {
  165.       SetABPenDrMd(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[TEXTPEN],
  166.                    msg->lvdm_DrawInfo->dri_Pens[BACKGROUNDPEN],JAM2);
  167.     }
  168.     else {
  169.       SetABPenDrMd(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[FILLTEXTPEN],
  170.                    msg->lvdm_DrawInfo->dri_Pens[FILLPEN],JAM2);
  171.     }
  172.     Text(msg->lvdm_RastPort,buffer,1);
  173.     if (msg->lvdm_RastPort->cp_x < msg->lvdm_Bounds.MinX+length) {
  174.       if (!ExtNode->Selected) {
  175.         SetAPen(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[BACKGROUNDPEN]);
  176.       }
  177.       else {
  178.         SetAPen(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[FILLPEN]);
  179.       }
  180.       RectFill(msg->lvdm_RastPort,msg->lvdm_RastPort->cp_x,msg->lvdm_Bounds.MinY,
  181.                msg->lvdm_Bounds.MinX-1+length,msg->lvdm_Bounds.MaxY);
  182.     }
  183.     Move(msg->lvdm_RastPort,msg->lvdm_Bounds.MinX+length,
  184.          msg->lvdm_Bounds.MinY+msg->lvdm_RastPort->TxBaseline);
  185.     if (!ExtNode->Selected) {
  186.       SetABPenDrMd(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[TEXTPEN],
  187.                    msg->lvdm_DrawInfo->dri_Pens[BACKGROUNDPEN],JAM2);
  188.     }
  189.     else {
  190.       SetABPenDrMd(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[FILLTEXTPEN],
  191.                    msg->lvdm_DrawInfo->dri_Pens[FILLPEN],JAM2);
  192.     }
  193.     Text(msg->lvdm_RastPort,ExtNode->Node.ln_Name,len);
  194.     if (!ExtNode->Selected) {
  195.       SetAPen(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[BACKGROUNDPEN]);
  196.     }
  197.     else {
  198.       SetAPen(msg->lvdm_RastPort,msg->lvdm_DrawInfo->dri_Pens[FILLPEN]);
  199.     }
  200.     RectFill(msg->lvdm_RastPort,msg->lvdm_RastPort->cp_x,msg->lvdm_Bounds.MinY,
  201.              msg->lvdm_Bounds.MaxX,msg->lvdm_Bounds.MaxY);
  202.     break;
  203.   default:
  204.     break;
  205.   }
  206.   return LVCB_OK;
  207. }
  208.  
  209.  
  210. static UWORD ComputeX( UWORD value )
  211. {
  212.     return(( UWORD )((( FontX * value ) + 3 ) / 6 ));
  213. }
  214.  
  215. static UWORD ComputeY( UWORD value )
  216. {
  217.     return(( UWORD )((( FontY * value ) + 5 ) / 10 ));
  218. }
  219.  
  220. static void ComputeFont( UWORD width, UWORD height )
  221. {
  222.     Font = &Attr;
  223.     Font->ta_Name = (STRPTR)Scr->RastPort.Font->tf_Message.mn_Node.ln_Name;
  224.     Font->ta_YSize = FontY = Scr->RastPort.Font->tf_YSize;
  225.     FontX = Scr->RastPort.Font->tf_XSize;
  226.  
  227.     OffX = Scr->WBorLeft;
  228.     OffY = Scr->RastPort.TxHeight + Scr->WBorTop + 1;
  229.  
  230.     if ( width && height ) {
  231.         if (( ComputeX( width ) + OffX + Scr->WBorRight ) > Scr->Width )
  232.             goto UseTopaz;
  233.         if (( ComputeY( height ) + OffY + Scr->WBorBottom ) > Scr->Height )
  234.             goto UseTopaz;
  235.     }
  236.     return;
  237.  
  238. UseTopaz:
  239.     Font->ta_Name = (STRPTR)"topaz.font";
  240.     FontX = FontY = Font->ta_YSize = 8;
  241. }
  242.  
  243. int SetupScreen( void )
  244. {
  245.     if ( ! ( Scr = LockPubScreen( PubScreenName )))
  246.         return( 1L );
  247.  
  248.     ComputeFont( 0, 0 );
  249.  
  250.     if ( ! ( VisualInfo = GetVisualInfo( Scr, TAG_DONE )))
  251.         return( 2L );
  252.  
  253.     return( 0L );
  254. }
  255.  
  256. void CloseDownScreen( void )
  257. {
  258.     if ( VisualInfo ) {
  259.         FreeVisualInfo( VisualInfo );
  260.         VisualInfo = NULL;
  261.     }
  262.  
  263.     if ( Scr        ) {
  264.         UnlockPubScreen( NULL, Scr );
  265.         Scr = NULL;
  266.     }
  267. }
  268.  
  269. typedef int (FPTR(void));
  270.  
  271. int HandleMultiListIDCMP( void )
  272. {
  273.     struct IntuiMessage    *m;
  274.     int            (*func)(void);
  275.     BOOL            running = TRUE;
  276.  
  277.     while( m = GT_GetIMsg( MultiListWnd->UserPort )) {
  278.  
  279.         CopyMem(( char * )m, ( char * )&MultiListMsg, (long)sizeof( struct IntuiMessage ));
  280.  
  281.         GT_ReplyIMsg( m );
  282.  
  283.         switch ( MultiListMsg.Class ) {
  284.  
  285.             case    IDCMP_REFRESHWINDOW:
  286.                 GT_BeginRefresh( MultiListWnd );
  287.                 GT_EndRefresh( MultiListWnd, TRUE );
  288.                 break;
  289.  
  290.             case    IDCMP_CLOSEWINDOW:
  291.                 running = MultiListCloseWindow();
  292.                 break;
  293.  
  294.             case    IDCMP_GADGETUP:
  295.             case    IDCMP_GADGETDOWN:
  296.                 func = ( FPTR * )(( struct Gadget * )MultiListMsg.IAddress )->UserData;
  297.                 running = func();
  298.                 break;
  299.  
  300.             case    IDCMP_VANILLAKEY:
  301.                 running = MultiListVanillaKey();
  302.                 break;
  303.         }
  304.     }
  305.     return( running );
  306. }
  307.  
  308. int OpenMultiListWindow( void )
  309. {
  310.     struct NewGadget    ng;
  311.     struct Gadget    *g;
  312.     UWORD        lc, tc;
  313.     UWORD        wleft = MultiListLeft, wtop = MultiListTop, ww, wh;
  314.  
  315.     ComputeFont( MultiListWidth, MultiListHeight );
  316.  
  317.     ww = ComputeX( MultiListWidth );
  318.     wh = ComputeY( MultiListHeight );
  319.  
  320.     if (( wleft + ww + OffX + Scr->WBorRight ) > Scr->Width ) wleft = Scr->Width - ww;
  321.     if (( wtop + wh + OffY + Scr->WBorBottom ) > Scr->Height ) wtop = Scr->Height - wh;
  322.  
  323.     if ( ! ( g = CreateContext( &MultiListGList )))
  324.         return( 1L );
  325.  
  326.     for( lc = 0, tc = 0; lc < MultiList_CNT; lc++ ) {
  327.  
  328.         CopyMem((char * )&MultiListNGad[ lc ], (char * )&ng, (long)sizeof( struct NewGadget ));
  329.  
  330.         ng.ng_VisualInfo = VisualInfo;
  331.         ng.ng_TextAttr   = Font;
  332.         ng.ng_LeftEdge   = OffX + ComputeX( ng.ng_LeftEdge );
  333.         ng.ng_TopEdge    = OffY + ComputeY( ng.ng_TopEdge );
  334.         ng.ng_Width      = ComputeX( ng.ng_Width );
  335.         ng.ng_Height     = ComputeY( ng.ng_Height);
  336.  
  337.         MultiListGadgets[ lc ] = g = CreateGadgetA((ULONG)MultiListGTypes[ lc ], g, &ng, ( struct TagItem * )&MultiListGTags[ tc ] );
  338.  
  339.         while( MultiListGTags[ tc ] ) tc += 2;
  340.         tc++;
  341.  
  342.         if ( NOT g )
  343.             return( 2L );
  344.     }
  345.  
  346.     HookList.h_Entry = (ULONG (*)())HookEntryList;
  347.     HookList.h_Data     = NULL;
  348.  
  349.     if ( ! ( MultiListWnd = OpenWindowTags( NULL,
  350.                 WA_Left,    wleft,
  351.                 WA_Top,        wtop,
  352.                 WA_Width,    ww + OffX + Scr->WBorRight,
  353.                 WA_Height,    wh + OffY + Scr->WBorBottom,
  354.                 WA_IDCMP,    LISTVIEWIDCMP|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_VANILLAKEY,
  355.                 WA_Flags,    WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH,
  356.                 WA_Gadgets,    MultiListGList,
  357.                 WA_Title,    MultiListWdt,
  358.                 WA_ScreenTitle,    "Multi-select example",
  359.                 WA_PubScreen,    Scr,
  360.                 WA_Activate, TRUE,
  361.                 TAG_DONE )))
  362.     return( 4L );
  363.  
  364.     GT_RefreshWindow( MultiListWnd, NULL );
  365.  
  366.     return( 0L );
  367. }
  368.  
  369. void CloseMultiListWindow( void )
  370. {
  371.     if ( MultiListWnd        ) {
  372.         CloseWindow( MultiListWnd );
  373.         MultiListWnd = NULL;
  374.     }
  375.  
  376.     if ( MultiListGList      ) {
  377.         FreeGadgets( MultiListGList );
  378.         MultiListGList = NULL;
  379.     }
  380. }
  381.  
  382.  
  383. struct Requester Requester;
  384.  
  385. void DisableWindow(void) {
  386.     InitRequester(&Requester);
  387.     Request(&Requester,MultiListWnd);
  388.     SetWindowPointer(MultiListWnd, WA_BusyPointer, TRUE,
  389.                           WA_PointerDelay, TRUE,
  390.                           TAG_END);
  391. }
  392.  
  393. void EnableWindow(void) {
  394.     EndRequest(&Requester,MultiListWnd);
  395.     SetWindowPointer(MultiListWnd,
  396.                           TAG_END);
  397. }
  398.  
  399. int MListClicked( void )
  400. {
  401.     /* routine when gadget "_Multi Select List" is clicked. */
  402.   DisableWindow();  // This disables the whole window
  403.   GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  404.                     GTLV_Labels,~0,
  405.                     TAG_END);
  406.   MList0Nodes[CurEntry].Current = FALSE;
  407.   CurEntry = MultiListMsg.Code;
  408.   MList0Nodes[CurEntry].Current = TRUE;
  409.   if (MList0Nodes[MultiListMsg.Code].Selected) {
  410.     MList0Nodes[MultiListMsg.Code].Selected = FALSE;
  411.   }
  412.   else {
  413.     MList0Nodes[MultiListMsg.Code].Selected = TRUE;
  414.   }
  415.   GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  416.                     GTLV_Labels,(ULONG)&MList0List,
  417.                     TAG_END);
  418.   EnableWindow();  // This enables the whole window
  419.   return 1;
  420. }
  421.  
  422. int MultiListCloseWindow( void )
  423. {
  424.     /* routine for "IDCMP_CLOSEWINDOW". */
  425.     return 0;
  426. }
  427.  
  428. int MultiListVanillaKey( void )
  429. {
  430.     /* routine for "IDCMP_VANILLAKEY". */
  431.     switch (MultiListMsg.Code) {
  432.     case 'm':
  433.         DisableWindow();
  434.        GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  435.                    GTLV_Labels,~0,
  436.                    TAG_END);
  437.         MList0Nodes[CurEntry].Current = FALSE;
  438.         ++CurEntry;
  439.         if (ENTRYCOUNT == CurEntry) {
  440.             CurEntry = 0;
  441.         }
  442.         MList0Nodes[CurEntry].Current = TRUE;
  443.         GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  444.                          GTLV_Labels,(ULONG)&MList0List,
  445.                                 GTLV_Selected, CurEntry,
  446.                                 GTLV_MakeVisible, CurEntry,
  447.                                 TAG_END);
  448.         EnableWindow();
  449.         break;
  450.     case 'M':
  451.         DisableWindow();
  452.        GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  453.                    GTLV_Labels,~0,
  454.                    TAG_END);
  455.         MList0Nodes[CurEntry].Current = FALSE;
  456.         if (CurEntry) {
  457.             --CurEntry;
  458.         }
  459.         else {
  460.             CurEntry = ENTRYCOUNT-1;
  461.         }
  462.         MList0Nodes[CurEntry].Current = TRUE;
  463.         GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  464.                          GTLV_Labels,(ULONG)&MList0List,
  465.                                 GTLV_Selected, CurEntry,
  466.                                 GTLV_MakeVisible, CurEntry,
  467.                                 TAG_END);
  468.         EnableWindow();
  469.         break;
  470.     case ' ':
  471.         DisableWindow();
  472.        GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  473.                    GTLV_Labels,~0,
  474.                    TAG_END);
  475.         if (MList0Nodes[CurEntry].Selected) {
  476.             MList0Nodes[CurEntry].Selected = FALSE;
  477.         }
  478.         else {
  479.             MList0Nodes[CurEntry].Selected = TRUE;
  480.         }
  481.         GT_SetGadgetAttrs(MultiListGadgets[GDX_MList],MultiListWnd,NULL,
  482.                           GTLV_Labels,(ULONG)&MList0List,
  483.                                 GTLV_Selected, CurEntry,
  484.                                 GTLV_MakeVisible, CurEntry,
  485.                                 TAG_END);
  486.         EnableWindow();
  487.     }
  488.     return 1;
  489. }
  490.  
  491. int main(void) {
  492.     int notdone = 1;
  493.     if (!SetupScreen()) {
  494.         if (!OpenMultiListWindow()) {
  495.             while (notdone) {
  496.                 WaitPort(MultiListWnd->UserPort);
  497.                 notdone = HandleMultiListIDCMP();
  498.             }
  499.             CloseMultiListWindow();
  500.         }
  501.         CloseDownScreen();
  502.     }
  503.     return 0;
  504. }
  505.